home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / COMMUNIC / 0132.ZIP / SERIAL.PAS < prev    next >
Pascal/Delphi Source File  |  1985-04-28  |  6KB  |  313 lines

  1. {Communications routines for TURBO Pascal written by Alan Bishop
  2.  Handles standart COM1: ports with interrupt handling.  Includes
  3.  support for only one port, and with no overflow, parity, or other
  4.  such checking.  However, even some of the best communication programs
  5.  don't do this anyway, and I never use it.  If you make modifications,
  6.  please send me a copy if you have a simple way of doing it (CIS EMAIL,
  7.  Usenet, MCI Mail, etc)  Hope these are useful.
  8.  
  9. Alan Bishop - CIS      - 72405,647
  10.               Usenet   - bishop@ecsvax
  11.               MCI Mail - ABISHOP
  12.  
  13.  
  14. All routines copywrite 1984 by Alan Bishop.  To be used in any
  15. personal or public domain programs.  Permission to be used in
  16. any Freeware type program or any sold program must come from
  17. Alan Bishop.
  18. }
  19.  
  20. {$C-}
  21. program commcall;
  22.  
  23. const recv_buf_size = 2048;  {this may be changed to whatever size you need}
  24.  
  25. type buffer_pointer   = integer;  {just for readability}
  26.      smallstring      = string[2];  {for compatibility with my INKEY routine}
  27.      bigstring        = string[255];  {general purpose}
  28.      storage          = byte;  {readability}
  29.      check_bit        = (none,even);  {readability and expansion}
  30.  
  31. var buf_start, buf_end    : buffer_pointer;  {NOTE: these will change by them-
  32.                                              selves in the background}
  33.     recv_buffer           : array [1..recv_buf_size] of storage; {also self-
  34.                                                                   changing}
  35.     speed                 : integer;  {I don't know the top speed these
  36.                                        routines will handle}
  37.     dbits                 : 7..8;  {only ones most people use}
  38.     stop_bits             : 1..2;  {does anyone use 2?}
  39.     parity                : check_bit;  {even and none are the common ones}
  40.  
  41. procedure check_range(var range : integer);
  42.  
  43. {this is used to adjust buffer pointers}
  44.  
  45. begin
  46.  if range > recv_buf_size then range := 1;
  47. end;
  48.  
  49. function commpressed : boolean;
  50.  
  51. {like keypressed, but for the comm port}
  52.  
  53. begin
  54.  commpressed := (buf_start <> buf_end);
  55. end;
  56.  
  57. function cinkey : smallstring;
  58.  
  59. {returns nothing or a code from the buffer - 2 bytes are used for
  60.  ease of use with a two byte inkey routine}
  61.  
  62. var result : smallstring;
  63.     temp   : integer;
  64.  
  65. begin
  66.  if not commpressed then result := ''
  67.  else
  68.  begin
  69.   inline ($FA);  {very important}
  70.   temp := recv_buffer[buf_start];
  71.   buf_start := buf_start +1;
  72.   check_range(buf_start);
  73.   inline ($FB);  {very important}
  74.   result := chr(temp);
  75.  end;
  76.  cinkey := result;
  77. end;
  78.  
  79.  
  80. function carrier : boolean;
  81.  
  82. {true if carrier, false if not}
  83.  
  84. begin
  85.  carrier := odd(port[$3FE] shr 7);
  86. end;
  87.  
  88.  
  89. procedure set_up_recv_buffer;
  90.  
  91. {big procedure isn't it?}
  92.  
  93. begin
  94.  buf_start := 1;
  95.  buf_end   := 1;
  96. end;
  97.  
  98.  
  99. procedure set_baud(rate : integer);
  100.  
  101. {has no problems with non-standard bauds}
  102.  
  103. var a : byte;
  104.     divided : real;
  105.  
  106. begin
  107.  if rate<=9600 then
  108.  begin
  109.   speed := rate;
  110.   divided := 115200.0/rate;
  111.   rate := trunc(divided);
  112.   a := port[$3fb];
  113.   if a < 128 then a := a+128;
  114.   port[$3fb] := a;
  115.   port[$3f8] := lo(rate);
  116.   port[$3f9] := hi(rate);
  117.   port[$3fb] := a-128;
  118.  end;
  119. end;
  120.  
  121. procedure update_uart;
  122.  
  123. {uses dbits, stop_bits, and parity}
  124.  
  125. var a : byte;
  126.  
  127. begin
  128.  a := dbits-5;
  129.  if stop_bits = 2 then a := a + 4;
  130.  if parity = even then a := a + 24;
  131.  port[$3fb] := a;
  132. end;
  133.  
  134.  
  135. procedure init_port;
  136.  
  137. {sets up most anything necessary}
  138.  
  139. var a,b : integer;
  140.     buf_len : integer;
  141.  
  142. begin
  143.  update_uart;
  144.  port[$3f9] := 1;             {interupt enable}
  145.  a := port[$3fc];
  146.  if odd(a) then a := 1 else a := 0;   {keep terminal ready}
  147.  a := a+10;
  148.  port[$3fc] := a;                     {turn on req to send and out2}
  149.  a := port[$3fa];
  150.  port[$21]  := $c;
  151.  set_baud(1200);
  152.  buf_len := recv_buf_size;
  153.  
  154.  {this is the background routine}
  155.  
  156.  inline (
  157.   $1E/
  158.   $0E/
  159.   $1F/
  160.   $BA/*+23/
  161.   $B8/$0C/$25/
  162.   $CD/$21/
  163.   $8B/$BE/BUF_LEN/
  164.   $89/$3E/*+87/
  165.   $1F/
  166.   $2E/$8C/$1E/*+83/
  167.   $EB/$51/
  168.   $FB/
  169.   $1E/
  170.   $50/
  171.   $53/
  172.   $52/
  173.   $56/
  174.   $2E/$8E/$1E/*+70/
  175.   $BA/$F8/$03/
  176.   $EC/
  177.   $BE/RECV_BUFFER/
  178.   $8B/$1E/BUF_END/
  179.   $88/$40/$FF/
  180.   $43/
  181.   $E8/$22/$00/
  182.   $89/$1E/BUF_END/
  183.   $3B/$1E/BUF_START/
  184.   $75/$0C/
  185.   $8B/$1E/BUF_START/
  186.   $43/
  187.   $E8/$10/$00/
  188.   $89/$1E/BUF_START/
  189.   $BA/$20/$00/
  190.   $B0/$20/
  191.   $EE/
  192.   $5E/
  193.   $5A/
  194.   $5B/
  195.   $58/
  196.   $1F/
  197.   $CF/
  198.   $2E/$8B/$16/*+11/
  199.   $42/
  200.   $39/$DA/
  201.   $75/$03/
  202.   $BB/$01/$00/
  203.   $C3/
  204.   $00/$00/
  205.   $00/$01/
  206.   $90
  207.  );
  208. end;
  209.  
  210. procedure term_ready(state : boolean);
  211.  
  212. {send a true for on, false for off}
  213.  
  214. var a : byte;
  215.  
  216. begin
  217.  a := port[$3fc];
  218.  if odd(a) then a := a - 1;
  219.  a := a + ord(state);
  220.  port[$3fc] := a;
  221. end;
  222.  
  223. procedure remove_port;
  224.  
  225. {gets rid of most problems}
  226.  
  227. var a : byte;
  228.  
  229. begin
  230.  port[$3f9] := 0;
  231.  a := port[$3fc];
  232.  if odd(a) then a := 1 else a := 0;
  233.  port[$3fc] := a;
  234.  port[$21]  := $BC;
  235. end;
  236.  
  237. procedure write_byte(to_send : bigstring);
  238.  
  239. {sends out up to 255 bytes}
  240.  
  241. var a,b,c : byte;
  242.  
  243. begin
  244.  for b := 1 to length(to_send) do
  245.  begin
  246.   c := ord(to_send[b]);
  247.   repeat a := port[$3fd];
  248.   until odd(a shr 5);
  249.   port[$3f8] := c;
  250.  end;
  251. end;
  252.  
  253. procedure break;
  254.  
  255. {send a break}
  256.  
  257. var a,b : byte;
  258.  
  259. begin
  260.  a := port[$3fb];
  261.  b := a;
  262.  if b > 127 then b := b - 128;
  263.  if b <= 63 then b := b + 64;
  264.  port[$3fb] := b;
  265.  delay(400);
  266.  port[$3fb] := a;
  267. end;
  268.  
  269. procedure setup;
  270.  
  271. {initialize most stuff - you may want to replace this routine completely}
  272.  
  273. var a : byte;
  274.  
  275. begin
  276.  dbits        := 8;
  277.  parity       := none;
  278.  stop_bits    := 1;
  279.  speed        := 1200;
  280.  init_port;
  281.  term_ready(true);
  282. end;
  283.  
  284.  
  285. {    The following is a sample program illustrating the use of these
  286.      routines.  The '|' key exits and ESC sends a break.  Because
  287.      of TURBO's standard handling of function keys and other things
  288.      like that, they will also.
  289. }
  290.  
  291.  
  292. var leave : boolean;
  293.     a     : char;
  294.     b     : smallstring;
  295.  
  296. begin
  297.  setup;
  298.  leave := false;
  299.  while not leave do
  300.  begin
  301.   if keypressed then
  302.   begin
  303.    read(kbd,a);
  304.    if a = '|' then leave := true else
  305.    if a = chr(27) then break else
  306.    write_byte(a);
  307.   end;
  308.   if commpressed then write(cinkey);
  309.  end;
  310.  remove_port;
  311.  term_ready(false);
  312. end.
  313.